package com.yirui.serialcomm.core.util;


import cn.hutool.core.exceptions.UtilException;

import java.net.*;
import java.util.Enumeration;

/**
 * @create 2025/5/9
 * @since 1.0.0
 */
public class NetUtils {
    private static final String CLIENT_LOCAL_IP_PROPERTY = "com.alibaba.nacos.client.local.ip";
    private static final String CLIENT_LOCAL_PREFER_HOSTNAME_PROPERTY = "com.alibaba.nacos.client.local.preferHostname";
    private static final String LEGAL_LOCAL_IP_PROPERTY = "java.net.preferIPv6Addresses";
    private static final String DEFAULT_SOLVE_FAILED_RETURN = "resolve_failed";
    private static String localIp;
    private static InetAddress inetAddress;
    public NetUtils() {
    }

    public static String localIP() {
        if (localIp != null && localIp.trim().length()>0) {
            return localIp;
        } else if (System.getProperties().containsKey(CLIENT_LOCAL_IP_PROPERTY)) {
            return localIp = System.getProperty(CLIENT_LOCAL_IP_PROPERTY, getAddress());
        } else {
            localIp = getAddress();
            return localIp;
        }
    }

    private static String getAddress() {
        InetAddress inetAddress = findFirstNonLoopbackAddress();
        if (inetAddress == null) {
            return DEFAULT_SOLVE_FAILED_RETURN;
        } else {
            boolean preferHost = Boolean.parseBoolean(System.getProperty(CLIENT_LOCAL_PREFER_HOSTNAME_PROPERTY));
            return preferHost ? inetAddress.getHostName() : inetAddress.getHostAddress();
        }
    }

    public static String getLocalhostStr() {
        InetAddress localhost = getLocalhost();
        return null != localhost ? localhost.getHostAddress() : null;
    }

    public static InetAddress getLocalhost() {
        return findFirstNonLoopbackAddress();
    }

    public static String getLocalMacAddress() {
        return getMacAddress(getLocalhost());
    }

    public static String getMacAddress(InetAddress inetAddress) {
        return getMacAddress(inetAddress, "-");
    }

    public static String getMacAddress(InetAddress inetAddress, String separator) {
        if (null == inetAddress) {
            return null;
        } else {
            byte[] mac = getHardwareAddress(inetAddress);
            if (null != mac) {
                StringBuilder sb = new StringBuilder();

                for(int i = 0; i < mac.length; ++i) {
                    if (i != 0) {
                        sb.append(separator);
                    }

                    String s = Integer.toHexString(mac[i] & 255);
                    sb.append(s.length() == 1 ? 0 + s : s);
                }

                return sb.toString();
            } else {
                return null;
            }
        }
    }

    public static byte[] getLocalHardwareAddress() {
        return getHardwareAddress(getLocalhost());
    }

    public static byte[] getHardwareAddress(InetAddress inetAddress) {
        if (null == inetAddress) {
            return null;
        } else {
            try {
                NetworkInterface networkInterface = NetworkInterface.getByInetAddress(inetAddress);
                return null != networkInterface ? networkInterface.getHardwareAddress() : null;
            } catch (SocketException var2) {
                throw new UtilException(var2);
            }
        }
    }

    private static InetAddress findFirstNonLoopbackAddress() {
        if(inetAddress != null){
            return inetAddress;
        }
        inetAddress = findFirstNonLoopbackAddress2();
        return inetAddress;
    }

    private static InetAddress findFirstNonLoopbackAddress2() {
        InetAddress result = null;

        try {
            int lowest = 2147483647;
            Enumeration nics = NetworkInterface.getNetworkInterfaces();

            label55:
            while(true) {
                NetworkInterface ifc;
                do {
                    do {
                        if (!nics.hasMoreElements()) {
                            break label55;
                        }

                        ifc = (NetworkInterface)nics.nextElement();
                    } while(!ifc.isUp());
                } while(ifc.getIndex() >= lowest && result != null);

                lowest = ifc.getIndex();
                Enumeration addrs = ifc.getInetAddresses();

                while(addrs.hasMoreElements()) {
                    InetAddress address = (InetAddress)addrs.nextElement();
                    boolean isLegalIpVersion = Boolean.parseBoolean(System.getProperty(LEGAL_LOCAL_IP_PROPERTY)) ? address instanceof Inet6Address : address instanceof Inet4Address;
                    if (isLegalIpVersion && !address.isLoopbackAddress()) {
                        result = address;
                    }
                }
            }
        } catch (Exception var8) {
        }

        if (result != null) {
            return result;
        } else {
            try {
                return InetAddress.getLocalHost();
            } catch (UnknownHostException var7) {
                return null;
            }
        }
    }
}
